package com.sky.service.impl;


import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.*;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.AddressBookBusinessException;
import com.sky.exception.OrderBusinessException;
import com.sky.exception.ShoppingCartBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.mapper.ShoppingCartMapper;
import com.sky.result.PageResult;
import com.sky.result.Result;
import com.sky.service.OrderService;
import com.sky.vo.OrderStatisticsVO;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.websocket.WebSocketServer;
import io.swagger.util.Json;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;

import java.io.ObjectInputFilter;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class OrderServiceImpl implements OrderService {
    @Autowired
    private AddressBookMapper addressBookMapper;
    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private WebSocketServer webSocketServer;  //注入websocket长连接
    /**
     * 根据订单id取消订单
     *
     * @param id
     */
    @Override
    public void CancelOrder(Long id) {
        //先根据id查找订单状态
        Orders orders = orderMapper.selectById(id);
        if (orders != null) {
            //判断订单状态 待付款和待接单状态直接取消订单  已接单和派送中联系商家取消  已完成只能退款
            if (orders.getStatus() == 1) {
                orders.setStatus(Orders.CANCELLED);
                orders.setCancelTime(LocalDateTime.now());
                orderMapper.updateStatus(orders);
            } else if (orders.getStatus() == 2) {
                //已付款 但未接单  需要退款
                orders.setStatus(Orders.CANCELLED);
                orders.setPayStatus(Orders.REFUND);
                orders.setCancelTime(LocalDateTime.now());
                orderMapper.updateStatus(orders);
            }
            //这里可能会有错误
            if (orders.getStatus() == 3 || orders.getStatus() == 4 || orders.getStatus() == 5) {
                throw new OrderBusinessException(MessageConstant.ORDER_STATUS_ERROR);
            }
        }
    }

    /**
     * 提交订单
     *
     * @param dto
     * @return
     */
    @Transactional
    @Override
    public OrderSubmitVO sumbitShoppingCart(OrdersSubmitDTO dto) {
        //先根据地址id查找地址表 看地址是否为空
        AddressBook addressBook = addressBookMapper.getById(dto.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //然后查购物车表 看购物车是否为空
        Long userid = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userid);
        List<ShoppingCart> shoppingCartList = shoppingCartMapper.selectByShoppingCart(shoppingCart);
        if (shoppingCartList == null && shoppingCartList.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.ORDER_NOT_FOUND);
        }
        //最后提交数据到订单表
        Orders orders = new Orders();
        BeanUtils.copyProperties(dto, orders);
        orders.setAddress(addressBook.getCityName() + addressBook.getDistrictName() + addressBook.getDetail());
        orders.setUserId(userid);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setOrderTime(LocalDateTime.now());
        orders.setDeliveryStatus(Orders.PAID);
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setPayMethod(Orders.PAID);
        orders.setPayStatus(Orders.UN_PAID);
        orders.setPhone(addressBook.getPhone());
        orders.setConsignee(addressBook.getConsignee());
        orders.setPackAmount(dto.getTablewareNumber());
        orders.setTablewareStatus(Orders.PAID);
        orderMapper.insert(orders);
        //提交数据到订单详情表
        List<OrderDetail> orderDetails = new ArrayList<>();
        /*for (int i = 0; i < shoppingCartList.size(); i++) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(shoppingCartList.get(i),orderDetail);
            orderDetails.add(orderDetail);
            orderDetails.get(i).setOrderId(orders.getId());
        }*/
        for (ShoppingCart cart : shoppingCartList) {
            OrderDetail orderDetail = new OrderDetail();
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(orders.getId());
            orderDetails.add(orderDetail);
        }
        orderDetailMapper.insert(orderDetails);
        //清空当前购物车
        shoppingCartMapper.delete(shoppingCart);
        //封装返回值
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder().id(orders.getId())
                .orderNumber(orders.getNumber()).orderAmount(orders.getAmount()).orderTime(orders.getOrderTime())
                .build();
        return orderSubmitVO;
    }

    /**
     * 分页查询历史订单详情
     *
     * @param ordersPageQueryDTO
     * @return
     */
    @Override
    public PageResult pageQuery(OrdersPageQueryDTO ordersPageQueryDTO) {
        //开启分页查询
        PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());
        //从订单表查询历史订单
        /*Orders orders = new Orders();
        BeanUtils.copyProperties(ordersPageQueryDTO, orders);*/
        ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
        Page<OrderVO> orderVOPage = orderMapper.list(ordersPageQueryDTO);
        //从订单详情表查询订单详情
        //List<Long> list = new ArrayList<>();
        for (OrderVO orderVO : orderVOPage.getResult()) {
            Long id = orderVO.getId();
            List<OrderDetail> orderDetails = orderDetailMapper.setletByOrderId(id);
            orderVO.setOrderDetailList(orderDetails);
        }
        return new PageResult(orderVOPage.getTotal(), orderVOPage.getResult());
    }

    /**
     * 根据订单id查询订单详情
     *
     * @param id
     * @return
     */
    @Override
    public OrderVO getOrderDetailList(long id) {
        Orders orders = orderMapper.selectById(id);
        List<OrderDetail> orderDetails = orderDetailMapper.setletByOrderId(id);
        //封装数据
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(orderDetails);
        return orderVO;
    }

    /**
     * 再来一单
     *
     * @param id
     */
    @Override
    @Transactional
    public void orderAgain(Long id) {
        //根据id查找订单详情
        List<OrderDetail> orderDetails = orderDetailMapper.setletByOrderId(id);
        //把查到的数据添加到购物表里面
        //List<ShoppingCart> shoppingCartList = new ArrayList<>();
        if (orderDetails != null) {
            for (OrderDetail orderDetail : orderDetails) {
                ShoppingCart shoppingCart = new ShoppingCart();
                BeanUtils.copyProperties(orderDetail, shoppingCart);
                shoppingCart.setUserId(BaseContext.getCurrentId());
                // shoppingCartList.add(shoppingCart);
                shoppingCartMapper.insert(shoppingCart);
            }
        }
    }

    /**
     * 用户端条件分页查询订单
     *
     * @param pageQueryDTO
     * @return
     */
    @Override
    public PageResult adminPageQuery(OrdersPageQueryDTO pageQueryDTO) {
        PageHelper.startPage(pageQueryDTO.getPage(), pageQueryDTO.getPageSize());
        //查订单表数据
        Page<OrderVO> orderVOPage = orderMapper.list(pageQueryDTO);
        //查订单明细表
        for (OrderVO orderVO : orderVOPage.getResult()) {
            Long orderVOId = orderVO.getId();
            List<OrderDetail> orderDetails = orderDetailMapper.setletByOrderId(orderVOId);
            //String collect = orderDetails.stream().map(orderDetail -> orderDetail.toString()).collect(Collectors.joining());
            String orderdishes = "";
            for (OrderDetail orderDetail : orderDetails) {
                if (orderDetail.getDishId() != null && orderDetail.getDishFlavor() != null) {
                    orderdishes = orderDetail.getName() + "*" + orderDetail.getNumber()
                            + orderDetail.getDishFlavor() + "; " + orderdishes;
                } else {
                    orderdishes = orderDetail.getName() + "*" + orderDetail.getNumber() +
                            "; " + orderdishes;
                }
            }
            log.info("拼接后的orderdetail对象为:{}", orderdishes);
            orderVO.setOrderDishes(orderdishes);
        }
        return new PageResult(orderVOPage.getTotal(), orderVOPage.getResult());
    }

    /**
     * 查询各个状态的数量
     *
     * @return
     */
    @Override
    public OrderStatisticsVO getStatis() {
        //查询待接单2  待派送3 派送中4
        OrderStatisticsVO orderStatisticsVO = new OrderStatisticsVO();
        Integer status = Orders.TO_BE_CONFIRMED; //2
        Integer count = orderMapper.getStatus(status);
        orderStatisticsVO.setToBeConfirmed(count);
        status = Orders.CONFIRMED; //3
        count = orderMapper.getStatus(status);
        orderStatisticsVO.setConfirmed(count);
        status = Orders.DELIVERY_IN_PROGRESS; //4
        count = orderMapper.getStatus(status);
        orderStatisticsVO.setDeliveryInProgress(count);
        return orderStatisticsVO;
    }

    /**
     * 通过id查找订单详情
     *
     * @param id
     * @return
     */
    @Override
    public OrderVO getById(Long id) {
        //先查找订单表
        Orders orders = orderMapper.selectById(id);
        //再查找订单详细表
        List<OrderDetail> orderDetails = orderDetailMapper.setletByOrderId(orders.getId());
        OrderVO orderVO = new OrderVO();
        BeanUtils.copyProperties(orders, orderVO);
        orderVO.setOrderDetailList(orderDetails);
        return orderVO;
    }

    /**
     * 商家根据id接单
     *
     * @param id
     */
    @Override
    public void acceptOrder(Long id) {
        //改变订单表的状态
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.CONFIRMED); //3
        orderMapper.updateStatus(orders);
    }

    /**
     * 商家拒单
     *
     * @param dto
     */
    @Override
    public void rejectOrder(OrdersRejectionDTO dto) {
        Orders orders = new Orders();
        BeanUtils.copyProperties(dto, orders);
        //设置订单支付状态为退款 2
        orders.setPayStatus(Orders.REFUND);
        //设置订单状态为取消订单 6;
        orders.setStatus(Orders.CANCELLED);
        orderMapper.updateStatus(orders);
    }

    /**
     * 商家取消订单
     *
     * @param dto
     */
    @Override
    public void AdminCancelOrder(OrdersCancelDTO dto) {
        //商家取消订单的情况有  待付款、待派送、派送中、已完成状态 1 3 4 5 //修改订单支付状态为退款 2
        Orders orders = orderMapper.selectById(dto.getId());
        if (orders.getStatus() == 1) {
            orders.setStatus(Orders.CANCELLED);
            orders.setCancelReason(dto.getCancelReason());
            orders.setCancelTime(LocalDateTime.now());
            orderMapper.updateStatus(orders);
        }
        if (orders.getStatus() == 3 || orders.getStatus() == 4 || orders.getStatus() == 5) {
            orders.setPayStatus(Orders.REFUND);
            orders.setStatus(Orders.CANCELLED);
            orders.setCancelReason(dto.getCancelReason());
            orders.setCancelTime(LocalDateTime.now());
            orderMapper.updateStatus(orders);
        }
    }

    /**
     * 派送订单
     *
     * @param id
     */
    @Override
    public void deliverOrder(Long id) {
        Orders orders = new Orders();
        orders.setId(id);
        orders.setStatus(Orders.DELIVERY_IN_PROGRESS);
        orderMapper.updateStatus(orders);
    }

    /**
     * 商家完成订单
     *
     * @param id
     */
    @Override
    public void completeOrder(Long id) {
        Orders orders = new Orders();
        orders.setStatus(Orders.COMPLETED);
        orders.setDeliveryTime(LocalDateTime.now());
        orders.setId(id);
        orderMapper.updateStatus(orders);
    }

    /**
     * C端用户订单支付
     *
     * @param dto
     */
    @Override
    public void paymentOrder(OrdersPaymentDTO dto) {
        Orders orders = new Orders();
        orders.setNumber(dto.getOrderNumber());
        orders.setPayMethod(dto.getPayMethod());
        orders.setStatus(Orders.TO_BE_CONFIRMED);
        orders.setPayStatus(Orders.PAID);
        orders.setCheckoutTime(LocalDateTime.now());
        orderMapper.updatePayment(orders);

        //服务器通过websocket给前端发送消息
        //查找订单id
        Long id =  orderMapper.seleteIdByNumber(dto.getOrderNumber());
        HashMap<String,Object> map = new HashMap<>();
        map.put("type",1);  //类型1为客户支付完后对管理端提示
        map.put("orderId",id);
        map.put("content","订单号:"+dto.getOrderNumber());
        String jsonString = JSON.toJSONString(map);
        webSocketServer.sendToAllClient(jsonString);
    }

    /**
     * 用户催单  用websocket和前端保持长连接
     * @param id
     */
    @Override
    public void reminderOrder(Long id) {
        Orders orders = orderMapper.selectById(id);
        if (orders != null){
            HashMap map = new HashMap();
            map.put("type",2);  //2表示为用户催单
            map.put("orderId",id);
            map.put("content","订单为:"+orders.getNumber());
            String jsonString = JSON.toJSONString(map);
            webSocketServer.sendToAllClient(jsonString);
        }
    }

}
